home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Atari Compendium
/
The Atari Compendium (Toad Computers) (1994).iso
/
files
/
compress
/
arj_992a.lzh
/
MODE_1-3.S
< prev
next >
Wrap
Text File
|
1994-08-07
|
15KB
|
588 lines
;
; ARJ Mode 1-3 decode functions
; Size optimized
; (c) 1993 Mr Ni! (the Great) of the TOS-crew
;
; This function uses a BIG amount of stack space!
; It uses about 16kB!
; You can reduce this amount with 13320 bytes
; by suppyling A3 with a pointer to a 13320 bytes big
; workspace and removing the stack allocation and
; deallocation code at the right places in the source
; text. (total is 3 lines, 2 at the start, 1 at main rts)
;
;void decode(ulong origsize, char* depack_space, char* packed_data)
;
; CALL:
; D0 = Origsize
; A0 = ptr to depack space
; A1 = ptr to packed data
;
; RETURN
; depacked data in depack space
;
workspacesize EQU 13320
pointer EQU 0
rbuf_current EQU 4
c_table EQU 8
c_len EQU 8200
avail EQU 8710
left EQU 8712
right EQU 10750
pt_len EQU 12788
pt_table EQU 12808
; register usage:
; D0 =
; D1 =
; D2 = temporary usage
; D3 = byte count
; D4 = command tri-nibble
; D5 = const: #$100
; D6 = bitbuf, subbitbuf
; D7 = .H: command count, .B: bits in subbitbuf
;
; A0 = klad
; A1 = rbuf_current
; A2 = c_table
; A3 = workspace_ptr
; A4 = text_pointer
; A5 = c_len
; A6 = copy_pointer
; A7 = Stack pointer
decode:
movem.l D3-D7/A2-A6,-(SP) ;
lea -workspacesize(SP),SP ; or supply your own workspace here
lea (SP),A3 ; remove if alternative workspace supplied
movea.l A0,A4 ; depack space
move.l D0,D3 ; origsize
moveq #0,D7 ; bitcount = 0
move.w A1,D0 ; for checking rbuf_current
btst D7,D0 ; does readbuf_current point to an even address?
beq.s .cont ; yes
move.b (A1)+,D6 ; pop eight bits
moveq #8,D7 ; 8 bits in subbitbuf
lsl.w #8,D6
.cont:
moveq #$10,D4 ; push 16 (8) bits into bitbuf
sub.w D7,D4 ; subtract still available bits from d5
lsl.l D7,D6
move.w (A1)+,D6 ; word in subbitbuf
lsl.l D4,D6 ; fill bitbuf
swap D6
lea c_len-pointer(A3),A5 ;
lea c_table-c_len(A5),A2
lea pt_table-c_len(A5),A0 ;
.count_loop:
move.w D6,D2 ; bitbuf in d2
swap D7 ; size of Hufmann-block
dbra D7,.bnz_cont ; Hufmann block size > 0?
.blocksize_zero: ; load a new Hufmann table
movem.l D3/A0/A2/A4,-(SP)
move.w D2,D7 ; blocksize
subq.w #1,D7 ; adapt blocksize for dbra
swap D7 ; bitcount to LSW
moveq #$10,D0 ; pop 16 bits
bsr fillbits
moveq #$03,D2 ; call-values for read_pt_len()
moveq #$05,D1 ;
moveq #$13,D0 ;
bsr read_pt_len ; call read_pt_len
movea.l rbuf_current-c_len(A5),A1
;void read_c_len(void) ;
bsr.s .get_them2
move.w D2,D0
bne.s .n_niet_nul ;
bsr.s .get_them2
lea (A5),A0 ;
moveq #$7F,D1 ;
.loop_1:
clr.l (A0)+ ; clear table
dbra D1,.loop_1
lea c_table-pointer(A3),A0
move.w #$0FFF,D1
.loop_2:
move.w D2,(A0)+
dbra D1,.loop_2
bra .einde
.get_them2:
moveq #9,D0 ;
move.w D6,D2 ; bitbuf
lsr.w #7,D2 ; shift 'old' bits
bra fillbits
.n_niet_nul: ; *******************************
;
; Register usage:
;
; d0
; d1
; d2
; d3
; d4
; d5 = $13
; d6 = .l (sub) bitbuf
; d7 = .b bits in bitbuf
;
; a0 = temporary usage
; a1 = rbuf_current
; a2 = right
; a3 = rbuf_tail
; a4 = pt_table
; a5 = c_len
; a6 = left
; a7 = sp
;
lea pt_table-c_len(A5),A4 ; pt_table
lea right-c_len(A5),A2 ; right
lea left-c_len(A5),A6 ; left
move.w D0,D3 ; count
moveq #0,D4 ;
moveq #$13,D5 ;
moveq #0,D0 ;
.loop_3:
move.w D6,D0 ; sub bitbuf
lsr.w #8,D0 ; upper 8 bits
add.w D0,D0 ;
move.w 0(A4,D0.w),D2 ; check pt_table
bge.s .c_kleiner_NT ;
neg.w D2
moveq #7,D0 ;
move.w D6,D1 ; bitbuf
.loop_4: ;
add.w D2,D2 ;
btst D0,D1 ;
beq.s .links ;
move.w 0(A2,D2.w),D2 ;
cmp.w D5,D2 ;
dbcs D0,.loop_4 ;
bra.s .c_kleiner_NT ;
.links: ;
move.w 0(A6,D2.w),D2 ;
cmp.w D5,D2 ;
dbcs D0,.loop_4 ;
.c_kleiner_NT: ;
move.b pt_len-pt_table(A4,D2.w),D0 ;
bsr fillbits
cmp.w #2,D2 ;
bgt.s .c_groter_2 ;
beq.s .c_niet_1 ;
tst.w D2 ;
beq.s .loop_5_init ;
moveq #4,D0
bsr getbits
addq.w #2,D2 ;
bra.s .loop_5_init ;
.c_niet_1:
bsr.s .get_them2
add.w D5,D2 ;
.loop_5_init:
moveq #0,D0 ;
lea 0(A5,D4.w),A0 ;
add.w D2,D4 ;
.loop_5:
move.b D0,(A0)+ ;
dbra D2,.loop_5 ;
bra.s .loop_3_test ;
.c_groter_2:
moveq #0,D0 ;
subq.w #2,D2 ;
move.b D2,0(A5,D4.w) ;
.loop_3_test:
addq.w #1,D4 ;
cmp.w D4,D3 ;
bgt.s .loop_3 ;
move.w #$01FE,D1 ;
sub.w D4,D1 ;
lea 0(A5,D4.w),A0 ;
bra.s .loop_6_test ;
.loop_6:
move.b D0,(A0)+ ;
.loop_6_test:
dbra D1,.loop_6 ;
move.l A1,rbuf_current-c_len(A5)
lea c_table-c_len(A5),A1 ;
moveq #$0C,D1 ;
movea.l A5,A0 ;
move.w #$01FE,D0 ;
bsr make_table ;
movea.l rbuf_current-c_len(A5),A1
.einde:
moveq #-1,D2 ;
moveq #$05,D1 ;
moveq #$11,D0 ;
bsr read_pt_len ;
movea.l rbuf_current-c_len(A5),A1
movem.l (SP)+,D3/A0/A2/A4
move.w #$0100,D5 ; constant
swap D7 ; blocksize to LSW
move.w D6,D2
;***********************
;
; Register usage:
;
; d0 = temporary usage
; d1 = temporary usage
; d2 = temporary usage
; d3 = loopcount
; d4 = command byte
; d5 = const: $100
; d6 = (sub)bitbuf
; d7 = .h: command count, .b byte count
;
; a0 = pt_table
; a1 = rbuf_current
; a2 = c_table
; a3 = rbuf_tail
; a4 = text
; a5 = c_len
; a6 = source pointer
; a7 = (sp)
.bnz_cont:
swap D7 ; bitcount in LSW d7
lsr.w #4,D2 ; charactertable is 4096 bytes (=12 bits)
add.w D2,D2
move.w 0(A2,D2.w),D2 ; pop character
bmi.s .j_grotergelijk_nc
.decode_c_cont: ;
move.b 0(A5,D2.w),D0 ; pop 'charactersize' bits from buffer
bsr fillbits
sub.w D5,D2 ;
bcc.s .sliding_dic ;
move.b D2,(A4)+ ; push character into buffer
subq.l #1,D3
bne .count_loop
.decode_einde:
lea workspacesize(SP),SP; remove if alternative workspace supplied
movem.l (SP)+,D3-D7/A2-A6 ;
rts ;
.j_grotergelijk_nc:
moveq #$03,D1 ;
move.w #$01FE,D0
bsr.s .fidel_no
bra.s .decode_c_cont ;
.p_j_grotergelijk_np:
moveq #$07,D1 ;
moveq #$11,D0
bsr.s .fidel_no
bra.s .p_cont ;
.fidel_no:
neg.w D2
lea left-c_len(A5),A0 ;
lea right-left(A0),A6 ;
.mask_loop:
add.w D2,D2 ;
btst D1,D6 ;
bne.s .bitbuf_en_mask ;
move.w 0(A0,D2.w),D2 ;
cmp.w D0,D2 ;
dbcs D1,.mask_loop ;
lea pt_table-c_len(A5),A0 ;
rts
.bitbuf_en_mask:
move.w 0(A6,D2.w),D2 ;
cmp